#include "AlgoEvaluatorModuleBase.h"

class algo::AlgoEvaluatorModuleBasePrivate
{
public:
	algobase::TaskConfig mConfig;
	std::shared_ptr<AlgoEvaluatorDB> mDB;
	std::string mLastErrorMessage;
	double mWeight;

	AlgoEvaluatorModuleBasePrivate() 
	{
		mWeight = 100;
		mDB = nullptr;
	}
};

algo::AlgoEvaluatorModuleBase::AlgoEvaluatorModuleBase()
	: d(new algo::AlgoEvaluatorModuleBasePrivate)
{
}

algo::AlgoEvaluatorModuleBase::~AlgoEvaluatorModuleBase()
{
	delete d;
}

void algo::AlgoEvaluatorModuleBase::setTaskConfig(const algobase::TaskConfig& taskConfig)
{
	d->mConfig = taskConfig;
}

algobase::TaskConfig algo::AlgoEvaluatorModuleBase::getTaskConfig() const
{
	return d->mConfig;
}

void algo::AlgoEvaluatorModuleBase::setWeight(double weight)
{
	d->mWeight = weight;
}

double algo::AlgoEvaluatorModuleBase::getWeight() const
{
	return d->mWeight;
}

std::string algo::AlgoEvaluatorModuleBase::getLastErrorMessage() const
{
	return d->mLastErrorMessage;
}

void algo::AlgoEvaluatorModuleBase::setErrorMessage(const std::string& msg)
{
	d->mLastErrorMessage = msg;
}

double algo::AlgoEvaluatorModuleBase::benefitSigmoid(double x, double x0, double s) const
{
	if (s == 0)
	{
		// throw std::invalid_argument("Scaling factor s for benefit_sigmoid cannot be zero.");
		return 0.0;
	}
	return 1.0 / (1.0 + std::exp(-(x - x0) / s));
}

double algo::AlgoEvaluatorModuleBase::costSigmoid(double x, double x0, double s) const
{
	if (s == 0)
	{
		// throw std::invalid_argument("Scaling factor s for cost_sigmoid cannot be zero.");
		return 0;
	}
	// This is equivalent to 1.0 - benefit_sigmoid(x, x0, s),
	// but implementing directly for clarity and potential minor optimization.
	double val = 1.0 / (1.0 + std::exp(-(x - x0) / s));
	return 1.0 - val;
}

int algo::AlgoEvaluatorModuleBase::exec(const algobase::Path& path, double& result, algobase::EvaluateModuleCoords& indexCoords)
{
	if (path.empty()) {
		return -1;
	}

	indexCoords.resize(path.size());

	for (int i = 0; i < indexCoords.size(); ++i) 
	{
		indexCoords[i].Assign(path[i]);
		indexCoords[i].mResult = getWeight();
	}

	result = getWeight();
	return 0;
}

void algo::AlgoEvaluatorModuleBase::setDB(std::shared_ptr<algo::AlgoEvaluatorDB> db)
{
	d->mDB = db;
}

std::shared_ptr<algo::AlgoEvaluatorDB> algo::AlgoEvaluatorModuleBase::getDB() const
{
	return d->mDB;
}
